package web.filter;

import common.consts.Header;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import web.Registry;
import web.security.JWT;
import web.security.JwtClaim;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by aceyin on 15/6/29.
 */
public class AuthenticationFilter implements Filter {
    private static Logger LOGGER = LoggerFactory.getLogger(AuthenticationFilter.class);

    @Override
    public void init(FilterConfig config) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        String contextPath = request.getContextPath();
        String url = request.getRequestURI();
        String uri = url.substring(contextPath.length());
        String method = request.getMethod().toUpperCase();

        String check = method + ":" + uri;

        boolean underProtection = Registry.contains(check);

        if (underProtection) {
            String header = request.getHeader(Header.AUTHORIZATION);
            if (StringUtils.isBlank(header)) {
                LOGGER.warn("Receiving no '{}' header request for protected URL '{}', will return 401.", Header.AUTHORIZATION, check);
                response.sendError(401);
                return;
            }
            JwtClaim claim = JWT.getIdentity(header);
            long userid = claim.getUserid();
            if (userid <= 0) {
                LOGGER.warn("Receiving bad JWT claim request for URL '{}', will return 401.", uri);
                response.sendError(401);
                return;
            }
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}
